﻿
namespace 观察者模式和外观模式
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //观察者模式
            ConcreteSubject subject = new ConcreteSubject();
            //添加观察者
            subject.Attach(new ConcreteObserver(subject, "X"));
            subject.Attach(new ConcreteObserver(subject, "Y"));
            subject.Attach(new ConcreteObserver(subject, "Z"));
            subject.SubjectState = "ADC";
            subject.Notify();


            //外观模式
            Facede facede = new Facede();
            facede.MethodA();
            facede.MethodB();
            Console.ReadKey();

        }
    }

    /// <summary>
    /// 抽象通知者
    /// </summary>
    abstract class Subject
    {
        private IList<Observer> observerlist = new List<Observer>();
        /// <summary>
        /// 增加观察者
        /// </summary>
        /// <param name="observer"></param>
        public void Attach(Observer observer)
        {
            observerlist.Add(observer);
        }

        /// <summary>
        /// 移除
        /// </summary>
        /// <param name="observer"></param>
        public void Detach(Observer observer)
        {
            observerlist.Remove(observer);
        }
        /// <summary>
        /// 通知
        /// </summary>
        public void Notify()
        {
            foreach (Observer observer in observerlist)
            {
                observer.Update();
            }
        }
    }

    /// <summary>
    /// 抽象观察者
    /// </summary>
    abstract class Observer
    {
        public abstract void Update();
    }

    /// <summary>
    /// 具体主题或具体通知者
    /// </summary>
    class ConcreteSubject : Subject
    {
        private string subjectState;
        //具体被观察者状态.
        public string SubjectState
        {
            get { return subjectState; }
            set { subjectState = value; }
        }
    }
    class ConcreteObserver : Observer
    {
        private string _name;
        private string observerstate;
        private ConcreteSubject conCreteSubject;

        public ConcreteObserver(ConcreteSubject conCreteSubject, string name)
        {
            this.conCreteSubject = conCreteSubject;
            _name = name;
        }


        public override void Update()
        {
            observerstate = conCreteSubject.SubjectState;
            Console.WriteLine("观察者{0}的新状态是{1}", _name, observerstate);
        }

        public ConcreteSubject _subject
        {
            get { return conCreteSubject; }
            set { conCreteSubject = value; }
        }
    }

    public class SubSystemOne
    {
        public void MethodOne()
        {
            Console.WriteLine("子系统方法一");
        }
    }

    public class SubSystemTwo
    {
        public void MethodTwo()
        {
            Console.WriteLine("子系统方法二");
        }
    }

    public class SubSystemThree
    {
        public void MethodThree()
        {
            Console.WriteLine("子系统方法三");
        }
    }
    public class SubSystemFour
    {
        public void MethodFour()
        {
            Console.WriteLine("子系统方法四");
        }
    }


    class Facede
    {
        SubSystemOne one;
        SubSystemTwo two;
        SubSystemThree three;
        SubSystemFour four;

        public Facede()
        {
            one = new SubSystemOne();
            two = new SubSystemTwo();
            three = new SubSystemThree();
            four = new SubSystemFour();
        }

        public void MethodA()
        {
            Console.WriteLine("方法组A()----");
            one.MethodOne();
            two.MethodTwo();
            four.MethodFour();
        }

        public void MethodB()
        {
            Console.WriteLine("方法组B()----");
            two.MethodTwo();
            three.MethodThree();
        }
    }


}